#include <REGX52.H>

//引脚定义
sbit DS1302_SCLK=P3^6;
sbit DS1302_IO=P3^4;
sbit DS1302_CE=P3^5;

//寄存器写入地址/指令定义
#define DS1302_SECOND		0x80
#define DS1302_MINUTE		0x82
#define DS1302_HOUR			0x84
#define DS1302_DATE			0x86
#define DS1302_MONTH		0x88
#define DS1302_DAY			0x8A
#define DS1302_YEAR			0x8C
#define DS1302_WP			0x8E

//时间数组，索引0~6分别为年、月、日、时、分、秒、星期
char Timer[] = {24,8,19,19,10,10,1};

void DS1302_Init(void)
{
	DS1302_CE = 0;
	DS1302_SCLK = 0;
}

void DS1602_WriteByte(unsigned char Command,Data)//写入数据
{ 
	unsigned char i=0;
	DS1302_CE = 1;
	for(i=0;i<8;i++)//写入控制命令字，一位一位写入
	{
		DS1302_IO = Command&(0x01<<i);
		DS1302_SCLK = 1;//给一个高电平，这个就是上升沿
		DS1302_SCLK = 0;//这个相当于清零，给一个低电平，一个高低就会进去然后输入一位，符合时序
	}
	for(i=0;i<8;i++)//写入输入数据，一位一位写入
	{
		DS1302_IO = Data&(0x01<<i);
		DS1302_SCLK = 1;
		DS1302_SCLK = 0;
	}
	DS1302_CE = 0;
}

char DS1302_ReadByte(unsigned char Command)//读取数据
{
	unsigned char i=0;
	unsigned char Data = 0x00;
	Command = Command|0x01;//因为Command如果是写，或一下就先当与把最后一位变成1，就变成了读
	DS1302_CE = 1;
	for(i=0;i<8;i++)//读取命令字
	{
		DS1302_IO = Command&(0x01<<i);
		DS1302_SCLK = 0;//这里的读取时钟时序，因为你的读取时间是少一个，所以我先置0，在置1，就能对上时序
		DS1302_SCLK = 1;
	}
	for(i=0;i<8;i++)//读取时钟数据
	{
		DS1302_SCLK = 1;//这个是下降有效，所以我先给1，上面本来就是1，不影响，然后给0，就刚好是下降沿
		DS1302_SCLK = 0;
		if(DS1302_IO)
		{
			Data|=(0x01<<i);//如果读到了数据，那就或上读到的这个 i ，就是读到了数据1，如果没有，Data本身就是0
		}
	}
	DS1302_CE = 0;//取消读写
	DS1302_IO = 0;//读取后将IO设置为0，否则读出的数据会出错
	return Data;
}

void DS1302_TimeSet(void)
{
	DS1602_WriteByte(DS1302_WP,0x00);
	DS1602_WriteByte(DS1302_YEAR,Timer[0]/10*16+Timer[0]%10);//因为Timer是十进制，你写入的时候，接受的是16进制，所以转换，这个是转换规则，先取10进制高位，所以用除法，然后在*16变成16进制，这只针对2位十进制
	DS1602_WriteByte(DS1302_MONTH,Timer[1]/10*16+Timer[1]%10);
	DS1602_WriteByte(DS1302_DATE,Timer[2]/10*16+Timer[2]%10);
	DS1602_WriteByte(DS1302_HOUR,Timer[3]/10*16+Timer[3]%10);
	DS1602_WriteByte(DS1302_MINUTE,Timer[4]/10*16+Timer[4]%10);
	DS1602_WriteByte(DS1302_SECOND,Timer[5]/10*16+Timer[5]%10);
	DS1602_WriteByte(DS1302_DAY,Timer[6]/10*16+Timer[6]%10);
	DS1602_WriteByte(DS1302_WP,0x80);//关闭写保护
}

void DS1302_TimeShow(void)
{
	unsigned char tmp;
	tmp = DS1302_ReadByte(DS1302_YEAR);
	Timer[0] = tmp/16*10 + tmp%16;//因为拿回来的是16进制，但是我们输出的是10进制，所以用转化
	tmp = DS1302_ReadByte(DS1302_MONTH);
	Timer[1] = tmp/16*10 + tmp%16;
	tmp = DS1302_ReadByte(DS1302_DATE);
	Timer[2] = tmp/16*10 + tmp%16;
	tmp = DS1302_ReadByte(DS1302_HOUR);
	Timer[3] = tmp/16*10 + tmp%16;
	tmp = DS1302_ReadByte(DS1302_MINUTE);
	Timer[4] = tmp/16*10 + tmp%16;
	tmp = DS1302_ReadByte(DS1302_SECOND);
	Timer[5] = tmp/16*10 + tmp%16;
	tmp = DS1302_ReadByte(DS1302_DAY);
	Timer[6] = tmp/16*10 + tmp%16;
}

